/**
  **************************************************************************
  * @file     es8311.c
  * @version  v1.0.0
  * @date     2025-06-18
  * @brief    es8311初始化配置
  **************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "./es8311/es8311.h"
#include "./i2c/i2c.h"


/* Private variables ---------------------------------------------------------*/


/**
 * @brief       es8311写寄存器
 * @param       reg : 寄存器地址
 * @param       val : 要写入寄存器的值
 * @retval      0,成功
 *              其他,错误代码
 */
static uint8_t es8311_write_reg(uint8_t reg, uint8_t val)
{
    iic_start();

    iic_send_byte((ES8311_ADDR << 1) | 0);	/* 发送器件地址+写命令 */

    if (iic_wait_ack()) {
        return 1;					/* 等待应答(成功?/失败?) */
    }

    iic_send_byte(reg);				/* 写寄存器地址 */

    if (iic_wait_ack()) {
        return 2;					/* 等待应答(成功?/失败?) */
    }

    iic_send_byte(val & 0XFF);		/* 发送数据 */

    if (iic_wait_ack()) {
        return 3;					/* 等待应答(成功?/失败?) */
    }

    iic_stop();

    return 0;
}

/**
 * @brief       es8311读寄存器
 * @param       reg : 寄存器地址
 * @retval      读取到的数据
 */
static uint8_t es8311_read_reg(uint8_t reg)
{
    uint8_t temp = 0;

    iic_start();

    iic_send_byte((ES8311_ADDR << 1) | 0);	/* 发送器件地址+写命令 */

    if (iic_wait_ack()) {
        return 1;							/*等待应答(成功?/失败?) */
    }

    iic_send_byte(reg);						/* 写寄存器地址 */

    if (iic_wait_ack()) {
        return 1;							/* 等待应答(成功?/失败?) */
    }

    iic_start();
    iic_send_byte((ES8311_ADDR << 1) | 1);	/* 发送器件地址+读命令 */

    if (iic_wait_ack()) {
        return 1;							/* 等待应答(成功?/失败?) */
    }

    temp = iic_read_byte(0);

    iic_stop();

    return temp;
}


/**
 * @brief       es8311初始化
 * @param       mclk-时钟;rate-采样率
 * @retval      0,初始化正常
 *              其他,错误代码
 */
uint8_t es8311_init(void)
{
    iic_init();                     /* 初始化IIC接口 */
    
    es8311_write_reg(0x00, 0x1F);	/* 复位器件 */
	Delay_ms(20);
	
    es8311_write_reg(0x00, 0x00);
    es8311_write_reg(0x00, 0x80);	/* CSM_ON */
	
    es8311_write_reg(0x01, 0x3F);	/* 打开MCLK/DAC/ADC时钟 */
	
    es8311_write_reg(0x09, 0x0C);   /* SDIN16位模式 */
    es8311_write_reg(0x0A, 0x0C);   /* SDOUT16位模式 */
	
    es8311_write_reg(0x0D, 0x01);   /* Power up analog circuitry */
    es8311_write_reg(0x0E, 0x02);   /* Enable analog PGA, enable ADC modulator */
    es8311_write_reg(0x12, 0x00);   /* power-up DAC */
    es8311_write_reg(0x13, 0x10);   /* Enable output to HP drive */
    es8311_write_reg(0x1C, 0x6A);   /* ADC Equalizer bypass, cancel DC offset in digital domain */
    
	es8311_write_reg(0x37, 0x08);   /* DAC ramprate and bypass DAC equalizer */
	
    es8311_write_reg(0x32, 0xCC);   /* Set DAC Volume (255*80/100) */
    es8311_write_reg(0x17, 0xB2);   /* Set ADC Volume */
	
    es8311_write_reg(0x14, 0x1A);   /* Set max PGA Gain for Mic (differential input) and turn DIG_MIC off */

    return 0;
}


/**
 * @brief       设置es8311工作模式
 * @param       fmt : 工作模式
 *    @arg      0, 飞利浦标准I2S;
 *    @arg      1, MSB(左对齐);
 *    @arg      2, LSB(右对齐);
 *    @arg      3, PCM/DSP
 * @param       len : 数据长度
 *    @arg      0, 24bit
 *    @arg      1, 20bit
 *    @arg      2, 18bit
 *    @arg      3, 16bit
 *    @arg      4, 32bit
 * @retval      无
 */
void es8311_i2s_cfg(uint8_t fmt, uint8_t len)
{
    fmt &= 0X03;
    len &= 0X07;    /* 限定范围 */
    es8311_write_reg(0x09, (fmt << 0) | (len << 2));
	es8311_write_reg(0x0A, (fmt << 0) | (len << 2));
}

/**
 * @brief       设置耳机音量
 * @param       voluem : 音量大小(0 ~ 100)
 * @retval      无
 */
void es8311_hpvol_set(uint8_t volume)
{
    volume = (255 * volume) / 100;

    es8311_write_reg(0x32, volume);
}

/**
 * @brief       es8311 DAC/ADC配置
 * @param       dacen : dac使能(1) / 关闭(0)
 * @param       adcen : adc使能(1) / 关闭(0)
 * @retval      无
 */
void es8311_adda_cfg(uint8_t dacen, uint8_t adcen)
{
	if (dacen) {
		es8311_write_reg(0x12, (0 << 1));
	} else {
		es8311_write_reg(0x12, (1 << 1));
	}
    es8311_write_reg(0x14, (adcen << 4) | (adcen << 6));
}

/**
 * @brief       es8311 MIC增益设置(MIC PGA增益)
 * @param       gain : 0~10, 对应0~30dB  3dB/Step
 * @retval      无
 */
void es8311_mic_gain(uint8_t gain)
{
    gain &= 0x7F;
    gain |= 0x50;
    es8311_write_reg(0x14, gain);       /* R9,左右通道PGA增益设置 */
}

/**
 * @brief       es8311 ALC设置
 * @param       sel
 *   @arg       0,关闭ALC
 *   @arg       1,右通道ALC
 *   @arg       2,左通道ALC
 *   @arg       3,立体声ALC
 * @param       maxgain : 0~7,对应-6.5~+35.5dB
 * @param       minigain: 0~7,对应-12~+30dB 6dB/STEP
 * @retval      无
 */
void es8311_alc_ctrl(uint8_t sel, uint8_t maxgain, uint8_t mingain)
{
    uint8_t tempreg = 0;
    es8311_write_reg(0X35, sel << 7);
    tempreg |= (maxgain & 0x0F) << 4;
    tempreg |= mingain & 0x0F;
    es8311_write_reg(0X35, tempreg);
}

